package sui.skinning
{
    import flash.display.DisplayObjectContainer;
    import flash.display.Sprite;

    import sui.core.Component;
    import sui.core.sui_internal;
    import sui.plugins.IPlugin;
    import sui.reflect.Metadata;
    import sui.reflect.Property;
    import sui.reflect.Type;
    import sui.utils.$format;

    public class SkinningPlugin implements IPlugin
    {
        public function onConstruct(comp:Component, description:Type):void
        {
            var skin:* = comp.sui_internal::skin;
            //assign variables declared in the host
            for each (var variable:Property in description.variables)
            {
                processSkinMetadata(variable);
            }
            positioning();

            //
            function processSkinMetadata(variable:Property):void
            {
                var metadata:Metadata = variable.metadatas["Skin"];
                if (metadata != null)
                {
                    var variableName:String = variable.name;
                    var variableType:Class = variable.type;
                    if (skin.hasOwnProperty(variableName))
                    {
                        if (skin is variableType)
                        {
                            comp.sui_internal //
                                ::setVariableSkin(variableName, //
                                                  skin[variableName], //
                                                  metadata);
                        }
                        else
                        {
                            var x:int = skin[variableName].x;
                            var y:int = skin[variableName].y;
                            comp.sui_internal //
                                ::setVariableSkin(variableName, //
                                                  new variableType(skin[variableName]), //
                                                  metadata);
                            comp.addChild(comp[variableName]);
                            comp[variableName].x = x;
                            comp[variableName].y = y;
                        }
                    }
                    else if (!metadata.has("optional") || //
                        metadata.get("optional") != true)
                    {
                        throw new ReferenceError( //
                            $format("{0} is required in {1} but not found in skin {2}", //
                                    variableName, //
                                    comp + "", //
                                    skin + ""));
                    }
                }
            }

            ////////////////////
            //处理skin到component的布局，
            function positioning():void
            {
                //使用skin作为k
                comp.x = skin.x;
                comp.y = skin.y;

                if (skin is DisplayObjectContainer)
                {
                    while (skin.numChildren > 0)
                    {
                        comp.addChildAt(skin.getChildAt(skin.numChildren - 1), 0);
                    }
                    if (skin is Sprite)
                    {
                        comp.graphics.copyFrom(skin.graphics);
                    }
                }
                else
                {
                    comp.addChild(skin);
                    skin.x = 0;
                    skin.y = 0;
                }
            }
        }
    }
}
